package com.regent.central.bill.service.bean.mrp.delivery;

import com.regent.central.bill.common.ActionType;
import com.regent.central.bill.common.DateUtil;
import com.regent.central.bill.core.mrp.BillMaterialDelivery;
import com.regent.central.bill.core.mrp.BillMaterialDeliveryActions;
import com.regent.central.bill.core.mrp.BillMaterialDeliveryMissionSku;
import com.regent.central.bill.repository.mrp.BillMaterialDeliveryActionsMapper;
import com.regent.central.bill.repository.mrp.BillMaterialDeliveryMapper;
import com.regent.central.bill.repository.mrp.BillMaterialDeliveryMissionSkuMapper;
import com.regent.central.bill.repository.mrp.dto.delivery.*;
import com.regent.central.bill.service.bean.mrp.util.MrpOrderNoGenerateUtil;
import com.regent.central.bill.service.mrp.delivery.BillMaterialDeliveryService;
import com.regent.central.infrastructure.common.Uid;
import com.regent.central.infrastructure.service.bean.DomainServiceBean;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

@Service
public class BillMaterialDeliveryServiceBean extends DomainServiceBean<BillMaterialDeliveryMapper, BillMaterialDelivery> implements BillMaterialDeliveryService {

    @Resource
    private BillMaterialDeliveryMapper billMaterialDeliveryMapper;

    @Resource
    private BillMaterialDeliveryActionsMapper billMaterialDeliveryActionsMapper;

    @Resource
    private BillMaterialDeliveryMissionSkuMapper billMaterialDeliveryMissionSkuMapper;

    public BillMaterialDeliveryPageDTO findPage(BillMaterialDeliveryPageParam param){
        BillMaterialDeliveryPageDTO billMaterialDeliveryPageDTO = new BillMaterialDeliveryPageDTO();
        billMaterialDeliveryPageDTO.setPageNo(param.getPageNo());
        billMaterialDeliveryPageDTO.setPageSize(param.getPageSize());
        Integer pageNo = param.getPageNo();
        Integer pageSize = param.getPageSize();
        param.setPageNo((pageNo - 1) * pageSize);
        List<String> ids = billMaterialDeliveryMapper.findIdsForPage(param);
        if(ids!=null&&ids.size()>0){
            Integer total = billMaterialDeliveryMapper.totalCount(param);
            List<BillMaterialDeliveryListDTO> details = billMaterialDeliveryMapper.findDetailByIds(ids);
            billMaterialDeliveryPageDTO.setTotal(total);
            billMaterialDeliveryPageDTO.setList(details);
        }
        return billMaterialDeliveryPageDTO;
    }

    public List<String> findDeliveryOrderNosByUnitId(String unitId){
        return billMaterialDeliveryMapper.findDeliveryOrdersByUnitId(unitId);
    }

    @Transactional
    @Override
    public void createBill(CentralBillDeliveryCreateDTO createDTO) {
        List<CentralBillDeliveryCreateSkuDTO> skus = createDTO.getSkus();
        List<String> reportIds = createDTO.getReportIds();
        if (skus == null || skus.size() <= 0 || reportIds == null || reportIds.size() <= 0) {
            return;
        }

        BillMaterialDelivery billMaterialDelivery = new BillMaterialDelivery();
        billMaterialDelivery.setId(Uid.random());
        billMaterialDelivery.setBossUnitId(createDTO.getBossUnitId());
        billMaterialDelivery.setBossUnitId(createDTO.getBossUnitId());
        billMaterialDelivery.setUnitId(createDTO.getUnitId());
        String dateDeliveryStr = createDTO.getDateDelivery();
        Date dateDelivery = new Date();
        if (StringUtils.isNotBlank(dateDeliveryStr)) {
            dateDelivery = DateUtil.formatToDateDefault(dateDeliveryStr);
            dateDelivery = DateUtil.merge(dateDelivery, new Date());
        }
        billMaterialDelivery.setDateDelivery(dateDelivery);
        billMaterialDelivery.setStorehouseId(createDTO.getStorehouseId());
        billMaterialDelivery.setDeliveryCreatorId(createDTO.getDeliveryCreatorId());
        billMaterialDelivery.setDeliveryCreatorName(createDTO.getDeliveryCreatorName());
        String orderNo = createDTO.getOrderNo();
        if (StringUtils.isBlank(orderNo)) {
            orderNo = getOrderNumber(createDTO.getUnitId());
        }
        billMaterialDelivery.setOrderNo(orderNo);
        billMaterialDeliveryMapper.insertSelective(billMaterialDelivery);

        // 送料动作关联
        for (String reportId : reportIds) {
            BillMaterialDeliveryActions actions = new BillMaterialDeliveryActions();
            actions.setId(Uid.random());
            actions.setActionType(ActionType.MATERIAL_DELIVER.name());
            actions.setActionId(reportId);
            actions.setCentralBillMaterialDeliveryId(billMaterialDelivery.getId());
            billMaterialDeliveryActionsMapper.insertSelective(actions);
        }

        // 送料中台二级数据维护
        for (CentralBillDeliveryCreateSkuDTO sku : skus) {
            BillMaterialDeliveryMissionSku billMaterialDeliveryMissionSku = new BillMaterialDeliveryMissionSku();
            billMaterialDeliveryMissionSku.setId(Uid.random());
            billMaterialDeliveryMissionSku.setBillMaterialDeliveryId(billMaterialDelivery.getId());
            billMaterialDeliveryMissionSku.setFacMissionId(sku.getFacMissionId());
            billMaterialDeliveryMissionSku.setMaterialSkuId(sku.getMaterialSkuId());
            billMaterialDeliveryMissionSku.setSupplierId(sku.getSupplierId()==null?"":sku.getSupplierId());
            billMaterialDeliveryMissionSku.setMaterialNo(sku.getMaterialNo());
            billMaterialDeliveryMissionSku.setStyleNo(sku.getStyleNo());
            billMaterialDeliveryMissionSku.setQuantityDelivery(sku.getQuantity());
            billMaterialDeliveryMissionSku.setPosition(sku.getPosition());
            billMaterialDeliveryMissionSkuMapper.insertSelective(billMaterialDeliveryMissionSku);
        }

    }

    private String getOrderNumber(String unitId) {
        LocalDate now = LocalDate.now();
        String startDate = now.toString() + " 00:00:00";
        String endDate = now.toString() + " 23:59:59";
        LocalDateTime dateStart = LocalDateTime.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime dateEnd = LocalDateTime.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        int count = billMaterialDeliveryMapper.countBillDeliveryByUnitId(unitId, dateStart, dateEnd);
        return MrpOrderNoGenerateUtil.generate(count, "SL");
    }

    @Override
    public BillMaterialDeliveryDTO findDeliveryOrdersById(String id){
        BillMaterialDeliveryDTO billMaterialDeliveryDTO = billMaterialDeliveryMapper.findDeliveryById(id);
        if(billMaterialDeliveryDTO != null){
            List<BillMaterialDeliveryOrderDTO> billMaterialDeliveryOrderDTOS = billMaterialDeliveryMapper.findDeliveryOrderById(id);
            billMaterialDeliveryDTO.setBillMaterialDeliveryOrderDTOS(billMaterialDeliveryOrderDTOS);
        }
        return billMaterialDeliveryDTO;
    }

    @Override
    public List<BillMaterialDeliveryOrderDTO> findDeliveryOrderById(String id){
        List<BillMaterialDeliveryOrderDTO> billMaterialDeliveryOrderDTOS = billMaterialDeliveryMapper.findDeliveryOrderById(id);
        return billMaterialDeliveryOrderDTOS;
    }

    @Override
    public List<BillMaterialDeliveryListDTO> findDetailById(String deliverId){
        return billMaterialDeliveryMapper.findDetailById(deliverId);
    }

    @Transactional
    @Override
    public BillMaterialDeliveryUndoResult undo(String billMaterialDeliveryId) {
        BillMaterialDeliveryUndoResult result = new BillMaterialDeliveryUndoResult();
        if (StringUtils.isBlank(billMaterialDeliveryId)) {
            result.setSuccess(false);
            return result;
        }
        int effectCount = billMaterialDeliveryMapper.undoBill(billMaterialDeliveryId);
        if (effectCount <= 0) {
            result.setSuccess(false);
            return result;
        }

        // 查送料单下的所有送料上报ID
        List<String> reportIds = billMaterialDeliveryMapper.listActionReportIds(billMaterialDeliveryId);
        result.setReportIds(reportIds);

        List<BillMaterialDeliveryUndoSkuDTO> skus = billMaterialDeliveryMapper.listFacMissionSkuQuantity(billMaterialDeliveryId);
        result.setSkus(skus);
        return result;
    }
}